package cn.com.zhbs.netty;

import cn.com.zhbs.common.security.SpringTools;
import cn.com.zhbs.netty.messageListener.Listener;
import cn.com.zhbs.netty.utils.ServerUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.concurrent.GlobalEventExecutor;


/**
 * @author 陈治杰
 * @Title: EchoServerHandler
 * @Description: 自定义handler实现网络操作业务逻辑
 * @date 2021/7/1 17:32
 */
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter{
    private Listener listener = SpringTools.getApplicationContext().getBean(Listener.class);
    public static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        channels.add(ctx.channel());
        System.out.println(ctx.channel().remoteAddress()+":已经连接");
        System.out.println("当前共有"+channels.size()+"个客户端连接");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress()+":已经断开");

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        byte[] data = new byte[2];
        in.readBytes(data);
        short msg_length= ServerUtil.byte2short(data);
        byte[] msg_id = new byte[4];
        in.readBytes(msg_id);
        int msg_id_int=ServerUtil.bytes2IntBig(msg_id);
        byte[] msg_body= new byte[msg_length];
        in.readBytes(msg_body);
        listener.getListener(String.valueOf(msg_id_int)).task(msg_body,ctx);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 将未处决消息冲刷到远程节点， 并且关闭该Channel
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                .addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event =(IdleStateEvent)evt;

        String eventType = null;

        switch (event.state()){
            case READER_IDLE:
                eventType = "读空闲";
                break;
            case WRITER_IDLE:
                eventType = "写空闲";
                break;
            case ALL_IDLE:
                eventType ="读写空闲";
                break;
        }
        System.out.println(ctx.channel().remoteAddress() + "超时事件：" +eventType);
        ctx.channel().close();
    }

    /**
     * 异常处理
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //打印异常栈跟踪
        cause.printStackTrace();

        // 关闭该Channel
        ctx.close();
    }
}